﻿// <copyright file="Commands.cs" company="FCIS">
// You are welcome to do whatever you want with the code in this file
// </copyright>
// -----------------------------------------------------------------------

namespace ImagePackage.CommandLine
{
    using System;
    using System.Collections.Generic;
    using Core;
    using Core.PixelOperations;
    using Utilities;

    /// <summary>
    /// Static class having the command handlers
    /// </summary>
    public static class Commands
    {
        /// <summary>
        /// local images
        /// </summary>
        private static readonly Dictionary<string, Model.Image> images = new Dictionary<string, Model.Image>();

        /// <summary>
        /// Exit command.
        /// </summary>
        /// <param name="arguments">The arguments.</param>
        /// <returns>Always retruns false</returns>
        public static bool Exit(string[] arguments)
        {
            return false;
        }

        /// <summary>
        /// Helps the specified arguments.
        /// </summary>
        /// <param name="arguments">The arguments.</param>
        /// <returns>true if successful</returns>
        public static bool Help(string[] arguments)
        {
            try
            {
                foreach (KeyValuePair<string, CommandLineApplication.CommandInfo> keyValuePair in CommandLineApplication.Commands)
                {
                    Console.WriteLine(string.Format("{0}\t\t{1}", keyValuePair.Key, keyValuePair.Value.Description));
                }

                return true;
            }
            catch (Exception ex)
            {
                Logger.Error(ex);

                Console.WriteLine("We are so sorry, something really bad happened. Check the logs");
                return false;
            }
        }

        /// <summary>
        /// Greet command. Greets the user with given name
        /// </summary>
        /// <param name="arguments">The arguments.</param>
        /// <returns>returns true on success</returns>
        public static bool Hello(string[] arguments)
        {
            try
            {
                if (arguments.Length < 2)
                {
                    Console.WriteLine("{0} needs 1 argument", arguments[0]);
                    return true;
                }

                Console.WriteLine(string.Format("Hello {0}", arguments[1]));

                return true;
            }
            catch (Exception ex)
            {
                Logger.Error(ex);

                Console.WriteLine("We are so sorry, something really bad happened. Check the logs");
                return false;
            }
        }

        /// <summary>
        /// Open command. Opens the image with the specified file path
        /// </summary>
        /// <param name="arguments">The arguments.</param>
        /// <returns> returns true on success </returns>
        public static bool Open(string[] arguments)
        {
            try
            {
                if (arguments.Length < 3)
                {
                    Console.WriteLine("{0} needs 2 argument", arguments[0]);
                    return true;
                }

                if (images.ContainsKey(arguments[2]))
                {
                    Console.WriteLine("Error\n{0} variable is already used", arguments[1]);
                    return true;
                }

                IO.InOutService inOutService = new IO.InOutService();
                DateTime before = DateTime.Now;
                Model.Image image = inOutService.Open(arguments[1]);
                DateTime after = DateTime.Now;

                Console.WriteLine("{0} finished successfully in {1} milliseconds", arguments[0], (after - before).TotalMilliseconds);

                images.Add(arguments[2], image);

                return true;
            }
            catch (Exception ex)
            {
                Logger.Error(ex);

                Console.WriteLine("We are so sorry, something really bad happened. Check the logs");
                return false;
            }
        }

        /// <summary>
        /// Inverts the specified arguments.
        /// </summary>
        /// <param name="arguments">The arguments.</param>
        /// <returns><c>true</c> after success</returns>
        public static bool Invert(string[] arguments)
        {
            try
            {
                if (arguments.Length < 2)
                {
                    Console.WriteLine("Error\nUsage {0} varName", arguments[0]);
                    return true;
                }

                if (!images.ContainsKey(arguments[1]))
                {
                    Console.WriteLine("Error\n{0} variable is not found, use open command to open new images", arguments[1]);
                    return true;
                }

                IOperation invert;
                if (arguments.Length > 2 && arguments[2] == "-p")
                {
                    invert = new Core.PixelOperations.Parallel.Invert(images[arguments[1]]);
                }
                else
                {
                    invert = new Invert(images[arguments[1]]);
                }

                DateTime before = DateTime.Now;
                images[arguments[1]] = invert.Apply();
                DateTime after = DateTime.Now;

                Console.WriteLine("{0} finished successfully in {1} milliseconds", arguments[0], (after - before).TotalMilliseconds);
                return true;
            }
            catch (Exception ex)
            {
                Logger.Error(ex);

                Console.WriteLine("We are so sorry, something really bad happened. Check the logs");
                return false;
            }
        }

        /// <summary>
        /// Displays the image in the specified arguments.
        /// </summary>
        /// <param name="arguments">The arguments.</param>
        /// <returns><c>true</c> after success</returns>
        public static bool Display(string[] arguments)
        {
            try
            {
                if (arguments.Length < 2)
                {
                    Console.WriteLine("Error\nUsage {0} varName", arguments[0]);
                    return true;
                }

                if (!images.ContainsKey(arguments[1]))
                {
                    Console.WriteLine("Error\n{0} variable is not found, use open command to open new images", arguments[1]);
                    return true;
                }

                Console.WindowWidth = 128;

                Console.WindowHeight = Console.LargestWindowHeight;

                Console.WriteLine(images[arguments[1]].ToAscii());

                return true;
            }
            catch (Exception ex)
            {
                Logger.Error(ex);

                Console.WriteLine("We are so sorry, something really bad happened. Check the logs");
                return false;
            }
        }
    }
}